/*******************************************************************************
 * File name: 		gpdma.c
 * Description: 
 * Project: 		gpdma
 * Target: 			LPC1788
 * Compiler: 		arm-none-eabi-gcc
 * Date: 			Sep 28, 2012
 * Author: 			kuba
 * Based on: 		---
 ******************************************************************************/

/*==============================================================================
 Includes
==============================================================================*/
# include "LPC177x_8x.h"
# include "hdr_sc.h"
# include "macros.h"

# include "gpdma.h"
/*==============================================================================
 Defines
==============================================================================*/
# define GPDMA_CHANNELS       	8
# define BURST_NUM            	8
# define WIDTH_NUM            	3
# define PERIPH_CONNECTIONS   	29
# define TRANSFER_TYPE			8
# define REQ_SEL				16

/* GPDMA bits */
# define GPDMA_INT_TCCLR_INT_TCCLR0				SET_BIT(0)
# define GPDMA_INT_TCCLR_INT_TCCLR1				SET_BIT(1)
# define GPDMA_INT_TCCLR_INT_TCCLR2				SET_BIT(2)
# define GPDMA_INT_TCCLR_INT_TCCLR3				SET_BIT(3)
# define GPDMA_INT_TCCLR_INT_TCCLR4				SET_BIT(4)
# define GPDMA_INT_TCCLR_INT_TCCLR5				SET_BIT(5)
# define GPDMA_INT_TCCLR_INT_TCCLR6				SET_BIT(6)
# define GPDMA_INT_TCCLR_INT_TCCLR7				SET_BIT(7)

# define GPDMA_INT_ERR_CLR_INT_ERR0				SET_BIT(0)
# define GPDMA_INT_ERR_CLR_INT_ERR1				SET_BIT(1)
# define GPDMA_INT_ERR_CLR_INT_ERR2				SET_BIT(2)
# define GPDMA_INT_ERR_CLR_INT_ERR3				SET_BIT(3)
# define GPDMA_INT_ERR_CLR_INT_ERR4				SET_BIT(4)
# define GPDMA_INT_ERR_CLR_INT_ERR5				SET_BIT(5)
# define GPDMA_INT_ERR_CLR_INT_ERR6				SET_BIT(6)
# define GPDMA_INT_ERR_CLR_INT_ERR7				SET_BIT(7)

# define GPDMA_INT_TCSTAT_INT_TCSTATUS0			SET_BIT(0)
# define GPDMA_INT_TCSTAT_INT_TCSTATUS1			SET_BIT(1)
# define GPDMA_INT_TCSTAT_INT_TCSTATUS2			SET_BIT(2)
# define GPDMA_INT_TCSTAT_INT_TCSTATUS3			SET_BIT(3)
# define GPDMA_INT_TCSTAT_INT_TCSTATUS4			SET_BIT(4)
# define GPDMA_INT_TCSTAT_INT_TCSTATUS5			SET_BIT(5)
# define GPDMA_INT_TCSTAT_INT_TCSTATUS6			SET_BIT(6)
# define GPDMA_INT_TCSTAT_INT_TCSTATUS7			SET_BIT(7)

# define GPDMA_CONFIG_ENABLE					SET_BIT(0)
# define GPDMA_CONFIG_BIG_ENDIAN				SET_BIT(1) /* Big endian */

/* channel bits */
# define GPDMA_CH_CTRL_TRANSFER_SIZE_bit		0
# define GPDMA_CH_CTRL_TRANSFER_SIZE_mask		0x0FFF					/* 11:0 bit */

# define GPDMA_CH_CTRL_SB_SIZE_bit				12						/* source burst size */
# define GPDMA_CH_CTRL_SB_SIZE_1				SET_BITS(0x00, GPDMA_CH_CTRL_SB_SIZE_bit)
# define GPDMA_CH_CTRL_SB_SIZE_4				SET_BITS(0x01, GPDMA_CH_CTRL_SB_SIZE_bit)
# define GPDMA_CH_CTRL_SB_SIZE_8				SET_BITS(0x02, GPDMA_CH_CTRL_SB_SIZE_bit)
# define GPDMA_CH_CTRL_SB_SIZE_16				SET_BITS(0x03, GPDMA_CH_CTRL_SB_SIZE_bit)
# define GPDMA_CH_CTRL_SB_SIZE_32				SET_BITS(0x04, GPDMA_CH_CTRL_SB_SIZE_bit)
# define GPDMA_CH_CTRL_SB_SIZE_64				SET_BITS(0x05, GPDMA_CH_CTRL_SB_SIZE_bit)
# define GPDMA_CH_CTRL_SB_SIZE_128				SET_BITS(0x06, GPDMA_CH_CTRL_SB_SIZE_bit)
# define GPDMA_CH_CTRL_SB_SIZE_256				SET_BITS(0x07, GPDMA_CH_CTRL_SB_SIZE_bit)

# define GPDMA_CH_CTRL_DB_SIZE_bit				15						/* destination burst size */
# define GPDMA_CH_CTRL_DB_SIZE_1				SET_BITS(0x00, GPDMA_CH_CTRL_DB_SIZE_bit)
# define GPDMA_CH_CTRL_DB_SIZE_4				SET_BITS(0x01, GPDMA_CH_CTRL_DB_SIZE_bit)
# define GPDMA_CH_CTRL_DB_SIZE_8				SET_BITS(0x02, GPDMA_CH_CTRL_DB_SIZE_bit)
# define GPDMA_CH_CTRL_DB_SIZE_16				SET_BITS(0x03, GPDMA_CH_CTRL_DB_SIZE_bit)
# define GPDMA_CH_CTRL_DB_SIZE_32				SET_BITS(0x04, GPDMA_CH_CTRL_DB_SIZE_bit)
# define GPDMA_CH_CTRL_DB_SIZE_64				SET_BITS(0x05, GPDMA_CH_CTRL_DB_SIZE_bit)
# define GPDMA_CH_CTRL_DB_SIZE_128				SET_BITS(0x06, GPDMA_CH_CTRL_DB_SIZE_bit)
# define GPDMA_CH_CTRL_DB_SIZE_256				SET_BITS(0x07, GPDMA_CH_CTRL_DB_SIZE_bit)

# define GPDMA_CH_CTRL_SWIDTH_bit				18						/* source transfer width */
# define GPDMA_CH_CTRL_SWIDTH_8					SET_BITS(0x00, GPDMA_CH_CTRL_SWIDTH_bit)
# define GPDMA_CH_CTRL_SWIDTH_16				SET_BITS(0x01, GPDMA_CH_CTRL_SWIDTH_bit)
# define GPDMA_CH_CTRL_SWIDTH_32				SET_BITS(0x02, GPDMA_CH_CTRL_SWIDTH_bit)

# define GPDMA_CH_CTRL_DWIDTH_bit				21						/* destination transfer width */
# define GPDMA_CH_CTRL_DWIDTH_8					SET_BITS(0x00, GPDMA_CH_CTRL_DWIDTH_bit)
# define GPDMA_CH_CTRL_DWIDTH_16				SET_BITS(0x01, GPDMA_CH_CTRL_DWIDTH_bit)
# define GPDMA_CH_CTRL_DWIDTH_32				SET_BITS(0x02, GPDMA_CH_CTRL_DWIDTH_bit)

# define GPDMA_CH_CTRL_SI						SET_BIT(26)				/* source increment */
# define GPDMA_CH_CTRL_DI						SET_BIT(27)				/* destination increment */
# define GPDMA_CH_CTRL_PROT						SET_BIT(28)				/* protection */
# define GPDMA_CH_CTRL_I						SET_BIT(31)				/* terminal count interrupt enable bit */

# define GPDMA_CH_CFG_CHANNEL_EN				SET_BIT(0)
# define GPDMA_CH_CFG_SRC_PERIPH_bit			1
# define GPDMA_CH_CFG_DST_PERIPH_bit			6

# define GPDMA_CH_CFG_SRC_PERIPH_SD				SET_BITS(0x01, GPDMA_CH_CFG_SRC_PERIPH_bit) /* source peripherals */
# define GPDMA_CH_CFG_SRC_PERIPH_SSP0TX			SET_BITS(0x02, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_SSP0RX			SET_BITS(0x03, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_SSP1TX			SET_BITS(0x04, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_SSP1RX			SET_BITS(0x05, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_SSP2TX			SET_BITS(0x06, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_SSP2RX			SET_BITS(0x07, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_ADC			SET_BITS(0x08, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_DAC			SET_BITS(0x09, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART0TX		SET_BITS(0x0A, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART0RX		SET_BITS(0x0B, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART1TX		SET_BITS(0x0C, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART1RX		SET_BITS(0x0D, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART2TX		SET_BITS(0x0E, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART2RX		SET_BITS(0x0F, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_TIMER0MAT0		SET_BITS(0x00, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_TIMER0MAT1		SET_BITS(0x01, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_TIMER1MAT0		SET_BITS(0x02, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_TIMER1MAT1		SET_BITS(0x03, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_TIMER2MAT0		SET_BITS(0x04, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_TIMER2MAT1		SET_BITS(0x05, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_I2SCH0			SET_BITS(0x06, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_I2SCH1			SET_BITS(0x07, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART3TX		SET_BITS(0x0A, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART3RX		SET_BITS(0x0B, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART4TX		SET_BITS(0x0C, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_UART4RX		SET_BITS(0x0D, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_TIMER3MAT0		SET_BITS(0x0E, GPDMA_CH_CFG_SRC_PERIPH_bit)
# define GPDMA_CH_CFG_SRC_PERIPH_TIMER3MAT1		SET_BITS(0x0F, GPDMA_CH_CFG_SRC_PERIPH_bit)

# define GPDMA_CH_CFG_DST_PERIPH_SD				SET_BITS(0x01, GPDMA_CH_CFG_DST_PERIPH_bit)	/* destination peripherals */
# define GPDMA_CH_CFG_DST_PERIPH_SSP0TX			SET_BITS(0x02, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_SSP0RX			SET_BITS(0x03, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_SSP1TX			SET_BITS(0x04, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_SSP1RX			SET_BITS(0x05, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_SSP2TX			SET_BITS(0x06, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_SSP2RX			SET_BITS(0x07, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_ADC			SET_BITS(0x08, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_DAC			SET_BITS(0x09, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART0TX		SET_BITS(0x0A, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART0RX		SET_BITS(0x0B, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART1TX		SET_BITS(0x0C, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART1RX		SET_BITS(0x0D, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART2TX		SET_BITS(0x0E, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART2RX		SET_BITS(0x0F, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_TIMER0MAT0		SET_BITS(0x00, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_TIMER0MAT1		SET_BITS(0x01, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_TIMER1MAT0		SET_BITS(0x02, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_TIMER1MAT1		SET_BITS(0x03, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_TIMER2MAT0		SET_BITS(0x04, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_TIMER2MAT1		SET_BITS(0x05, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_I2SCH0			SET_BITS(0x06, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_I2SCH1			SET_BITS(0x07, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART3TX		SET_BITS(0x0A, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART3RX		SET_BITS(0x0B, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART4TX		SET_BITS(0x0C, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_UART4RX		SET_BITS(0x0D, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_TIMER3MAT0		SET_BITS(0x0E, GPDMA_CH_CFG_DST_PERIPH_bit)
# define GPDMA_CH_CFG_DST_PERIPH_TIMER3MAT1		SET_BITS(0x0F, GPDMA_CH_CFG_DST_PERIPH_bit)

# define GPDMA_CH_CFG_TRANSFER_TYPE_bit			11	/* transfer types */
# define GPDMA_CH_CFG_TRANSFER_TYPE_M2M_DMA		SET_BITS(0x0, GPDMA_CH_CFG_TRANSFER_TYPE_bit)	/* memory to memory, dma is flow controller */
# define GPDMA_CH_CFG_TRANSFER_TYPE_M2P_DMA		SET_BITS(0x1, GPDMA_CH_CFG_TRANSFER_TYPE_bit)	/* memory to periph, dma is flow controller */
# define GPDMA_CH_CFG_TRANSFER_TYPE_P2M_DMA		SET_BITS(0x2, GPDMA_CH_CFG_TRANSFER_TYPE_bit)	/* periph to memory, dma is flow controller */
# define GPDMA_CH_CFG_TRANSFER_TYPE_SP2DP_DMA	SET_BITS(0x3, GPDMA_CH_CFG_TRANSFER_TYPE_bit)	/* source periph to dest periph, dma is flow controller */
# define GPDMA_CH_CFG_TRANSFER_TYPE_SP2DP_DP	SET_BITS(0x4, GPDMA_CH_CFG_TRANSFER_TYPE_bit)	/* source periph to dest periph, dest periph is flow controller */
# define GPDMA_CH_CFG_TRANSFER_TYPE_M2P_P		SET_BITS(0x5, GPDMA_CH_CFG_TRANSFER_TYPE_bit)	/* memory to periph, periph is flow controller */
# define GPDMA_CH_CFG_TRANSFER_TYPE_P2M_P		SET_BITS(0x6, GPDMA_CH_CFG_TRANSFER_TYPE_bit)	/* periph to memory, periph is flow controller */
# define GPDMA_CH_CFG_TRANSFER_TYPE_SP2DP_SP	SET_BITS(0x7, GPDMA_CH_CFG_TRANSFER_TYPE_bit)	/* source periph to dest periph, source periph is flow controller */

# define GPDMA_CH_CFG_ITC						SET_BIT(15)

# define GPDMA_REQ_SEL_SEL00_UNUSED_TIMER0MAT0	SET_BIT(0)
# define GPDMA_REQ_SEL_SEL01_SD_TIMER0MAT1		SET_BIT(1)
# define GPDMA_REQ_SEL_SEL02_SSP0TX_TIMER1MAT0	SET_BIT(2)
# define GPDMA_REQ_SEL_SEL03_SSP0RX_TIMER1MAT1	SET_BIT(3)
# define GPDMA_REQ_SEL_SEL04_SSP1TX_TIMER2MAT0	SET_BIT(4)
# define GPDMA_REQ_SEL_SEL05_SSP1RX_TIMER2MAT1	SET_BIT(5)
# define GPDMA_REQ_SEL_SEL06_SSP2TX_I2SCH0		SET_BIT(6)
# define GPDMA_REQ_SEL_SEL07_SSP2RX_I2SCH1		SET_BIT(7)
# define GPDMA_REQ_SEL_RESERVED08				SET_BIT(8)
# define GPDMA_REQ_SEL_RESERVED09				SET_BIT(9)
# define GPDMA_REQ_SEL_SEL10_UART0TX_UART3TX	SET_BIT(10)
# define GPDMA_REQ_SEL_SEL11_UART0RX_UART3RX	SET_BIT(11)
# define GPDMA_REQ_SEL_SEL12_UART1TX_UART4TX	SET_BIT(12)
# define GPDMA_REQ_SEL_SEL13_UART1RX_UART4RX	SET_BIT(13)
# define GPDMA_REQ_SEL_SEL14_UART2TX_TIMER3MAT0	SET_BIT(14)
# define GPDMA_REQ_SEL_SEL15_UART2RX_TIMER3MAT1	SET_BIT(15)

# define GPDMA_REQ_SEL (*(uint32 *)0x400FC1C4)
/*==============================================================================
 Types
==============================================================================*/
struct gpdmaChannel {
   uint32 ctrl;
   uint32 conf;
   uint32 src;
   uint32 dst;
};

struct gpdmaService {
   void (*transferEndService)(void); /* user service at the end of transfer */
   void (*errorService)(void);       /* user service in case of error */
};

struct confLut {                          	/* configuration look up tables */
   uint32 srcBurst[BURST_NUM];            	/* source burst look up table */
   uint32 dstBurst[BURST_NUM];            	/* destination burst look up table */
   uint32 srcWidth[WIDTH_NUM];            	/* source width look up table */
   uint32 dstWidth[WIDTH_NUM];            	/* destination width look up table */
   uint32 srcPeriph[PERIPH_CONNECTIONS];  	/* source periheral look up table */
   uint32 dstPeriph[PERIPH_CONNECTIONS];  	/* destination periheral look up table */
   uint32 trsfrType[TRANSFER_TYPE];      	/* transfer type and flow control */
   uint32 reqSel[REQ_SEL];					/* request select- select between peripheral requests */
};

/*==============================================================================
 Globals
==============================================================================*/
static struct gpdmaChannel channelArray[GPDMA_CHANNELS];
static struct gpdmaService serviceArray[GPDMA_CHANNELS];
static const struct confLut lut = {
.srcBurst = {GPDMA_CH_CTRL_SB_SIZE_1,
		GPDMA_CH_CTRL_SB_SIZE_4,
		GPDMA_CH_CTRL_SB_SIZE_8,
		GPDMA_CH_CTRL_SB_SIZE_16,
		GPDMA_CH_CTRL_SB_SIZE_32,
		GPDMA_CH_CTRL_SB_SIZE_64,
		GPDMA_CH_CTRL_SB_SIZE_128,
		GPDMA_CH_CTRL_SB_SIZE_256},
.dstBurst = {GPDMA_CH_CTRL_DB_SIZE_1,
		GPDMA_CH_CTRL_DB_SIZE_4,
		GPDMA_CH_CTRL_DB_SIZE_8,
		GPDMA_CH_CTRL_DB_SIZE_16,
		GPDMA_CH_CTRL_DB_SIZE_32,
		GPDMA_CH_CTRL_DB_SIZE_64,
		GPDMA_CH_CTRL_DB_SIZE_128,
		GPDMA_CH_CTRL_DB_SIZE_256},
.srcWidth = {GPDMA_CH_CTRL_SWIDTH_8, GPDMA_CH_CTRL_SWIDTH_16, GPDMA_CH_CTRL_SWIDTH_32},
.dstWidth = {GPDMA_CH_CTRL_DWIDTH_8, GPDMA_CH_CTRL_DWIDTH_16, GPDMA_CH_CTRL_DWIDTH_32},
.srcPeriph = {GPDMA_CH_CFG_SRC_PERIPH_SD,
				GPDMA_CH_CFG_SRC_PERIPH_SSP0TX,
				GPDMA_CH_CFG_SRC_PERIPH_SSP0RX,
				GPDMA_CH_CFG_SRC_PERIPH_SSP1TX,
				GPDMA_CH_CFG_SRC_PERIPH_SSP1RX,
				GPDMA_CH_CFG_SRC_PERIPH_SSP2TX,
				GPDMA_CH_CFG_SRC_PERIPH_SSP2RX,
				GPDMA_CH_CFG_SRC_PERIPH_ADC,
				GPDMA_CH_CFG_SRC_PERIPH_DAC,
				GPDMA_CH_CFG_SRC_PERIPH_UART0TX,
				GPDMA_CH_CFG_SRC_PERIPH_UART0RX,
				GPDMA_CH_CFG_SRC_PERIPH_UART1TX,
				GPDMA_CH_CFG_SRC_PERIPH_UART1RX,
				GPDMA_CH_CFG_SRC_PERIPH_UART2TX,
				GPDMA_CH_CFG_SRC_PERIPH_UART2RX,
				GPDMA_CH_CFG_SRC_PERIPH_TIMER0MAT0,
				GPDMA_CH_CFG_SRC_PERIPH_TIMER0MAT1,
				GPDMA_CH_CFG_SRC_PERIPH_TIMER1MAT0,
				GPDMA_CH_CFG_SRC_PERIPH_TIMER1MAT1,
				GPDMA_CH_CFG_SRC_PERIPH_TIMER2MAT0,
				GPDMA_CH_CFG_SRC_PERIPH_TIMER2MAT1,
				GPDMA_CH_CFG_SRC_PERIPH_I2SCH0,
				GPDMA_CH_CFG_SRC_PERIPH_I2SCH1,
				GPDMA_CH_CFG_SRC_PERIPH_UART3TX,
				GPDMA_CH_CFG_SRC_PERIPH_UART3RX,
				GPDMA_CH_CFG_SRC_PERIPH_UART4TX,
				GPDMA_CH_CFG_SRC_PERIPH_UART4RX,
				GPDMA_CH_CFG_SRC_PERIPH_TIMER3MAT0,
				GPDMA_CH_CFG_SRC_PERIPH_TIMER3MAT1},
		.dstPeriph = {GPDMA_CH_CFG_DST_PERIPH_SD,
				GPDMA_CH_CFG_DST_PERIPH_SSP0TX,
				GPDMA_CH_CFG_DST_PERIPH_SSP0RX,
				GPDMA_CH_CFG_DST_PERIPH_SSP1TX,
				GPDMA_CH_CFG_DST_PERIPH_SSP1RX,
				GPDMA_CH_CFG_DST_PERIPH_SSP2TX,
				GPDMA_CH_CFG_DST_PERIPH_SSP2RX,
				GPDMA_CH_CFG_DST_PERIPH_ADC,
				GPDMA_CH_CFG_DST_PERIPH_DAC,
				GPDMA_CH_CFG_DST_PERIPH_UART0TX,
				GPDMA_CH_CFG_DST_PERIPH_UART0RX,
				GPDMA_CH_CFG_DST_PERIPH_UART1TX,
				GPDMA_CH_CFG_DST_PERIPH_UART1RX,
				GPDMA_CH_CFG_DST_PERIPH_UART2TX,
				GPDMA_CH_CFG_DST_PERIPH_UART2RX,
				GPDMA_CH_CFG_DST_PERIPH_TIMER0MAT0,
				GPDMA_CH_CFG_DST_PERIPH_TIMER0MAT1,
				GPDMA_CH_CFG_DST_PERIPH_TIMER1MAT0,
				GPDMA_CH_CFG_DST_PERIPH_TIMER1MAT1,
				GPDMA_CH_CFG_DST_PERIPH_TIMER2MAT0,
				GPDMA_CH_CFG_DST_PERIPH_TIMER2MAT1,
				GPDMA_CH_CFG_DST_PERIPH_I2SCH0,
				GPDMA_CH_CFG_DST_PERIPH_I2SCH1,
				GPDMA_CH_CFG_DST_PERIPH_UART3TX,
				GPDMA_CH_CFG_DST_PERIPH_UART3RX,
				GPDMA_CH_CFG_DST_PERIPH_UART4TX,
				GPDMA_CH_CFG_DST_PERIPH_UART4RX,
				GPDMA_CH_CFG_DST_PERIPH_TIMER3MAT0,
				GPDMA_CH_CFG_DST_PERIPH_TIMER3MAT1},
		.trsfrType = {GPDMA_CH_CFG_TRANSFER_TYPE_M2M_DMA,
				GPDMA_CH_CFG_TRANSFER_TYPE_M2P_DMA,
				GPDMA_CH_CFG_TRANSFER_TYPE_P2M_DMA,
				GPDMA_CH_CFG_TRANSFER_TYPE_SP2DP_DMA,
				GPDMA_CH_CFG_TRANSFER_TYPE_SP2DP_DP,
				GPDMA_CH_CFG_TRANSFER_TYPE_M2P_P,
				GPDMA_CH_CFG_TRANSFER_TYPE_P2M_P,
				GPDMA_CH_CFG_TRANSFER_TYPE_SP2DP_SP},
		.reqSel = {GPDMA_REQ_SEL_SEL00_UNUSED_TIMER0MAT0,
				GPDMA_REQ_SEL_SEL01_SD_TIMER0MAT1,
				GPDMA_REQ_SEL_SEL02_SSP0TX_TIMER1MAT0,
				GPDMA_REQ_SEL_SEL03_SSP0RX_TIMER1MAT1,
				GPDMA_REQ_SEL_SEL04_SSP1TX_TIMER2MAT0,
				GPDMA_REQ_SEL_SEL05_SSP1RX_TIMER2MAT1,
				GPDMA_REQ_SEL_SEL06_SSP2TX_I2SCH0,
				GPDMA_REQ_SEL_SEL07_SSP2RX_I2SCH1,
				GPDMA_REQ_SEL_RESERVED08,
				GPDMA_REQ_SEL_RESERVED09,
				GPDMA_REQ_SEL_SEL10_UART0TX_UART3TX,
				GPDMA_REQ_SEL_SEL11_UART0RX_UART3RX,
				GPDMA_REQ_SEL_SEL12_UART1TX_UART4TX,
				GPDMA_REQ_SEL_SEL13_UART1RX_UART4RX,
				GPDMA_REQ_SEL_SEL14_UART2TX_TIMER3MAT0,
				GPDMA_REQ_SEL_SEL15_UART2RX_TIMER3MAT1}
};


/*==============================================================================
 Static function prototypes
==============================================================================*/
static void dummyService (void);

/*==============================================================================
 Global function definitions
==============================================================================*/
/*------------------------------------------------------------------------------
 function name:   gpdmaInit
 description:     GPDMA module initialization
 parameters:      interrupt priority
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaInit (enum irqPriority priority)
{
	/* power for GPDMA */
	LPC_SC->PCONP |= LPC_SC_PCONP_PCGPDMA;
	/* clear Terminal Count interrupts for channels 0 to 7 */
	LPC_GPDMA->IntTCClear = (GPDMA_INT_TCCLR_INT_TCCLR0 | GPDMA_INT_TCCLR_INT_TCCLR1
			| GPDMA_INT_TCCLR_INT_TCCLR2 | GPDMA_INT_TCCLR_INT_TCCLR3
			| GPDMA_INT_TCCLR_INT_TCCLR4 | GPDMA_INT_TCCLR_INT_TCCLR5
			| GPDMA_INT_TCCLR_INT_TCCLR6 | GPDMA_INT_TCCLR_INT_TCCLR7);
	/* clear Error interrupts for channels 0 to 7 */
	LPC_GPDMA->IntErrClr = (GPDMA_INT_ERR_CLR_INT_ERR0 | GPDMA_INT_ERR_CLR_INT_ERR1
 	  	  	  | GPDMA_INT_ERR_CLR_INT_ERR2 | GPDMA_INT_ERR_CLR_INT_ERR3
 	  	  	  | GPDMA_INT_ERR_CLR_INT_ERR4 | GPDMA_INT_ERR_CLR_INT_ERR5
 	  	  	  | GPDMA_INT_ERR_CLR_INT_ERR6 | GPDMA_INT_ERR_CLR_INT_ERR7);
	/* enable GPDMA, and little-endian is left 0 (default) */
	LPC_GPDMA->Config = GPDMA_CONFIG_ENABLE;
	/* wait till GPDMA is enabled */
	while (!(LPC_GPDMA->Config & GPDMA_CONFIG_ENABLE));

	NVIC_SetPriority(DMA_IRQn, priority);		/* set priority in NVIC */
	NVIC_EnableIRQ(DMA_IRQn);					/* enable interrupt in NVIC */
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl0Init
 description:     channel 0 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl0Init   (const struct gpdmaConf *gpdmaConf)
{
	   gpdmaChannel tmp;

	   /* remember channel settings */
	   tmp = &channelArray[0];

	   /* set function pointers in case they are 0 */
	   if (gpdmaConf->transferEndService == 0)
	   {
	      serviceArray[0].transferEndService = dummyService;
	   }
	   else
	   {
	      serviceArray[0].transferEndService = gpdmaConf->transferEndService;
	   }

	   if (gpdmaConf->errorService == 0)
	   {
	      serviceArray[0].errorService = dummyService;
	   }
	   else
	   {
	      serviceArray[0].errorService = gpdmaConf->errorService;
	   }

	   /* set control word */
	   switch (gpdmaConf->mode)
	   {
	   case gpdmaM2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2M */

	   case gpdmaM2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2P */

	   case gpdmaP2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaP2M */

	   case gpdmaP2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_I);
	      break;            /* end of gpdmaP2P */

	   default:
	      tmp->ctrl = 0;
	      break;   /* wrong mode */
	   }
	   /* set configuartion word */
	   tmp->conf = lut.srcPeriph[gpdmaConf->srcPeriph] | lut.dstPeriph[gpdmaConf->dstPeriph] |
			   lut.trsfrType[gpdmaConf->flowCtrl] | GPDMA_CH_CFG_ITC;
	   /* set source and destination */
	   tmp->src = gpdmaConf->srcAddr;
	   tmp->dst = gpdmaConf->dstAddr;
	   /* set request select register */
	   if (gpdmaConf->srcPeriph > gpdmaSRC_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->srcPeriph - 15));
	   }
	   if (gpdmaConf->dstPeriph > gpdmaDST_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->dstPeriph - 15));
	   }

	   return tmp;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl1Init
 description:     channel 1 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl1Init (const struct gpdmaConf *gpdmaConf)
{
	   gpdmaChannel tmp;

	   /* remember channel settings */
	   tmp = &channelArray[1];

	   /* set function pointers in case they are 0 */
	   if (gpdmaConf->transferEndService == 0)
	   {
	      serviceArray[1].transferEndService = dummyService;
	   }
	   else
	   {
	      serviceArray[1].transferEndService = gpdmaConf->transferEndService;
	   }

	   if (gpdmaConf->errorService == 0)
	   {
	      serviceArray[1].errorService = dummyService;
	   }
	   else
	   {
	      serviceArray[1].errorService = gpdmaConf->errorService;
	   }

	   /* set control word */
	   switch (gpdmaConf->mode)
	   {
	   case gpdmaM2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2M */

	   case gpdmaM2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2P */

	   case gpdmaP2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaP2M */

	   case gpdmaP2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_I);
	      break;            /* end of gpdmaP2P */

	   default:
	      tmp->ctrl = 0;
	      break;   /* wrong mode */
	   }
	   /* set configuartion word */
	   tmp->conf = lut.srcPeriph[gpdmaConf->srcPeriph] | lut.dstPeriph[gpdmaConf->dstPeriph] |
			   lut.trsfrType[gpdmaConf->flowCtrl] | GPDMA_CH_CFG_ITC;
	   /* set source and destination */
	   tmp->src = gpdmaConf->srcAddr;
	   tmp->dst = gpdmaConf->dstAddr;
	   /* set request select register */
	   if (gpdmaConf->srcPeriph > gpdmaSRC_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->srcPeriph - 15));
	   }
	   if (gpdmaConf->dstPeriph > gpdmaDST_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->dstPeriph - 15));
	   }

	   return tmp;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl2Init
 description:     channel 2 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl2Init (const struct gpdmaConf *gpdmaConf)
{
	   gpdmaChannel tmp;

	   /* remember channel settings */
	   tmp = &channelArray[2];

	   /* set function pointers in case they are 0 */
	   if (gpdmaConf->transferEndService == 0)
	   {
	      serviceArray[2].transferEndService = dummyService;
	   }
	   else
	   {
	      serviceArray[2].transferEndService = gpdmaConf->transferEndService;
	   }

	   if (gpdmaConf->errorService == 0)
	   {
	      serviceArray[2].errorService = dummyService;
	   }
	   else
	   {
	      serviceArray[2].errorService = gpdmaConf->errorService;
	   }

	   /* set control word */
	   switch (gpdmaConf->mode)
	   {
	   case gpdmaM2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2M */

	   case gpdmaM2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2P */

	   case gpdmaP2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaP2M */

	   case gpdmaP2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_I);
	      break;            /* end of gpdmaP2P */

	   default:
	      tmp->ctrl = 0;
	      break;   /* wrong mode */
	   }
	   /* set configuartion word */
	   tmp->conf = lut.srcPeriph[gpdmaConf->srcPeriph] | lut.dstPeriph[gpdmaConf->dstPeriph] |
			   lut.trsfrType[gpdmaConf->flowCtrl] | GPDMA_CH_CFG_ITC;
	   /* set source and destination */
	   tmp->src = gpdmaConf->srcAddr;
	   tmp->dst = gpdmaConf->dstAddr;
	   /* set request select register */
	   if (gpdmaConf->srcPeriph > gpdmaSRC_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->srcPeriph - 15));
	   }
	   if (gpdmaConf->dstPeriph > gpdmaDST_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->dstPeriph - 15));
	   }

	   return tmp;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl3Init
 description:     channel 3 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl3Init (const struct gpdmaConf *gpdmaConf)
{
	   gpdmaChannel tmp;

	   /* remember channel settings */
	   tmp = &channelArray[3];

	   /* set function pointers in case they are 0 */
	   if (gpdmaConf->transferEndService == 0)
	   {
	      serviceArray[3].transferEndService = dummyService;
	   }
	   else
	   {
	      serviceArray[3].transferEndService = gpdmaConf->transferEndService;
	   }

	   if (gpdmaConf->errorService == 0)
	   {
	      serviceArray[3].errorService = dummyService;
	   }
	   else
	   {
	      serviceArray[3].errorService = gpdmaConf->errorService;
	   }

	   /* set control word */
	   switch (gpdmaConf->mode)
	   {
	   case gpdmaM2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2M */

	   case gpdmaM2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2P */

	   case gpdmaP2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaP2M */

	   case gpdmaP2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_I);
	      break;            /* end of gpdmaP2P */

	   default:
	      tmp->ctrl = 0;
	      break;   /* wrong mode */
	   }
	   /* set configuartion word */
	   tmp->conf = lut.srcPeriph[gpdmaConf->srcPeriph] | lut.dstPeriph[gpdmaConf->dstPeriph] |
			   lut.trsfrType[gpdmaConf->flowCtrl] | GPDMA_CH_CFG_ITC;
	   /* set source and destination */
	   tmp->src = gpdmaConf->srcAddr;
	   tmp->dst = gpdmaConf->dstAddr;
	   /* set request select register */
	   if (gpdmaConf->srcPeriph > gpdmaSRC_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->srcPeriph - 15));
	   }
	   if (gpdmaConf->dstPeriph > gpdmaDST_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->dstPeriph - 15));
	   }

	   return tmp;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl4Init
 description:     channel 4 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl4Init (const struct gpdmaConf *gpdmaConf)
{
	   gpdmaChannel tmp;

	   /* remember channel settings */
	   tmp = &channelArray[4];

	   /* set function pointers in case they are 0 */
	   if (gpdmaConf->transferEndService == 0)
	   {
	      serviceArray[4].transferEndService = dummyService;
	   }
	   else
	   {
	      serviceArray[4].transferEndService = gpdmaConf->transferEndService;
	   }

	   if (gpdmaConf->errorService == 0)
	   {
	      serviceArray[4].errorService = dummyService;
	   }
	   else
	   {
	      serviceArray[4].errorService = gpdmaConf->errorService;
	   }

	   /* set control word */
	   switch (gpdmaConf->mode)
	   {
	   case gpdmaM2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2M */

	   case gpdmaM2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2P */

	   case gpdmaP2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaP2M */

	   case gpdmaP2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_I);
	      break;            /* end of gpdmaP2P */

	   default:
	      tmp->ctrl = 0;
	      break;   /* wrong mode */
	   }
	   /* set configuartion word */
	   tmp->conf = lut.srcPeriph[gpdmaConf->srcPeriph] | lut.dstPeriph[gpdmaConf->dstPeriph] |
			   lut.trsfrType[gpdmaConf->flowCtrl] | GPDMA_CH_CFG_ITC;
	   /* set source and destination */
	   tmp->src = gpdmaConf->srcAddr;
	   tmp->dst = gpdmaConf->dstAddr;
	   /* set request select register */
	   if (gpdmaConf->srcPeriph > gpdmaSRC_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->srcPeriph - 15));
	   }
	   if (gpdmaConf->dstPeriph > gpdmaDST_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->dstPeriph - 15));
	   }

	   return tmp;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl5Init
 description:     channel 5 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl5Init (const struct gpdmaConf *gpdmaConf)
{
	   gpdmaChannel tmp;

	   /* remember channel settings */
	   tmp = &channelArray[5];

	   /* set function pointers in case they are 0 */
	   if (gpdmaConf->transferEndService == 0)
	   {
	      serviceArray[5].transferEndService = dummyService;
	   }
	   else
	   {
	      serviceArray[5].transferEndService = gpdmaConf->transferEndService;
	   }

	   if (gpdmaConf->errorService == 0)
	   {
	      serviceArray[5].errorService = dummyService;
	   }
	   else
	   {
	      serviceArray[5].errorService = gpdmaConf->errorService;
	   }

	   /* set control word */
	   switch (gpdmaConf->mode)
	   {
	   case gpdmaM2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2M */

	   case gpdmaM2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2P */

	   case gpdmaP2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaP2M */

	   case gpdmaP2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_I);
	      break;            /* end of gpdmaP2P */

	   default:
	      tmp->ctrl = 0;
	      break;   /* wrong mode */
	   }
	   /* set configuartion word */
	   tmp->conf = lut.srcPeriph[gpdmaConf->srcPeriph] | lut.dstPeriph[gpdmaConf->dstPeriph] |
			   lut.trsfrType[gpdmaConf->flowCtrl] | GPDMA_CH_CFG_ITC;
	   /* set source and destination */
	   tmp->src = gpdmaConf->srcAddr;
	   tmp->dst = gpdmaConf->dstAddr;
	   /* set request select register */
	   if (gpdmaConf->srcPeriph > gpdmaSRC_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->srcPeriph - 15));
	   }
	   if (gpdmaConf->dstPeriph > gpdmaDST_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->dstPeriph - 15));
	   }

	   return tmp;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl6Init
 description:     channel 6 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl6Init (const struct gpdmaConf *gpdmaConf)
{
	   gpdmaChannel tmp;

	   /* remember channel settings */
	   tmp = &channelArray[6];

	   /* set function pointers in case they are 0 */
	   if (gpdmaConf->transferEndService == 0)
	   {
	      serviceArray[6].transferEndService = dummyService;
	   }
	   else
	   {
	      serviceArray[6].transferEndService = gpdmaConf->transferEndService;
	   }

	   if (gpdmaConf->errorService == 0)
	   {
	      serviceArray[6].errorService = dummyService;
	   }
	   else
	   {
	      serviceArray[6].errorService = gpdmaConf->errorService;
	   }

	   /* set control word */
	   switch (gpdmaConf->mode)
	   {
	   case gpdmaM2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2M */

	   case gpdmaM2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2P */

	   case gpdmaP2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaP2M */

	   case gpdmaP2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_I);
	      break;            /* end of gpdmaP2P */

	   default:
	      tmp->ctrl = 0;
	      break;   /* wrong mode */
	   }
	   /* set configuartion word */
	   tmp->conf = lut.srcPeriph[gpdmaConf->srcPeriph] | lut.dstPeriph[gpdmaConf->dstPeriph] |
			   lut.trsfrType[gpdmaConf->flowCtrl] | GPDMA_CH_CFG_ITC;
	   /* set source and destination */
	   tmp->src = gpdmaConf->srcAddr;
	   tmp->dst = gpdmaConf->dstAddr;
	   /* set request select register */
	   if (gpdmaConf->srcPeriph > gpdmaSRC_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->srcPeriph - 15));
	   }
	   if (gpdmaConf->dstPeriph > gpdmaDST_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->dstPeriph - 15));
	   }

	   return tmp;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl7Init
 description:     channel 7 initialization
 parameters:      pointer to configuration struct
 returned value:  channel settings
------------------------------------------------------------------------------*/
gpdmaChannel gpdmaChnl7Init (const struct gpdmaConf *gpdmaConf)
{
	   gpdmaChannel tmp;

	   /* remember channel settings */
	   tmp = &channelArray[7];

	   /* set function pointers in case they are 0 */
	   if (gpdmaConf->transferEndService == 0)
	   {
	      serviceArray[7].transferEndService = dummyService;
	   }
	   else
	   {
	      serviceArray[7].transferEndService = gpdmaConf->transferEndService;
	   }

	   if (gpdmaConf->errorService == 0)
	   {
	      serviceArray[7].errorService = dummyService;
	   }
	   else
	   {
	      serviceArray[7].errorService = gpdmaConf->errorService;
	   }

	   /* set control word */
	   switch (gpdmaConf->mode)
	   {
	   case gpdmaM2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2M */

	   case gpdmaM2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_SI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaM2P */

	   case gpdmaP2M:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_DI) | (GPDMA_CH_CTRL_I);
	      break; /* end of gpdmaP2M */

	   case gpdmaP2P:
	      tmp->ctrl = lut.srcBurst[gpdmaConf->sbSize] | lut.dstBurst[gpdmaConf->dbSize]
	                  | lut.srcWidth[gpdmaConf->srcWidth] | lut.dstWidth[gpdmaConf->dstWidth]
	                  | (GPDMA_CH_CTRL_I);
	      break;            /* end of gpdmaP2P */

	   default:
	      tmp->ctrl = 0;
	      break;   /* wrong mode */
	   }
	   /* set configuartion word */
	   tmp->conf = lut.srcPeriph[gpdmaConf->srcPeriph] | lut.dstPeriph[gpdmaConf->dstPeriph] |
			   lut.trsfrType[gpdmaConf->flowCtrl] | GPDMA_CH_CFG_ITC;
	   /* set source and destination */
	   tmp->src = gpdmaConf->srcAddr;
	   tmp->dst = gpdmaConf->dstAddr;
	   /* set request select register */
	   if (gpdmaConf->srcPeriph > gpdmaSRC_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->srcPeriph - 15));
	   }
	   if (gpdmaConf->dstPeriph > gpdmaDST_PERIPH_UART2RX)
	   {
		   GPDMA_REQ_SEL |= (1 << (gpdmaConf->dstPeriph - 15));
	   }

	   return tmp;
}
/*------------------------------------------------------------------------------
 function name:   gpdmaChnl0Enable
 description:     enable channel 0
 parameters:      channel settings
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl0Enable (const gpdmaChannel chnl, const uint16 size)
{
	/* clear pending TC interrupt in channel */
	LPC_GPDMA->IntTCClear = GPDMA_INT_TCCLR_INT_TCCLR0;
	/* clear pending errors in channel */
	LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR0;
	/* set source address */
	LPC_GPDMACH0->CSrcAddr = chnl->src;
	/* set destination address */
	LPC_GPDMACH0->CDestAddr = chnl->dst;
	/* no list */
	LPC_GPDMACH0->CLLI = 0;
	/* set control word */
	LPC_GPDMACH0->CControl = chnl->ctrl | (size & GPDMA_CH_CTRL_TRANSFER_SIZE_mask);
	/* set configuration word */
	LPC_GPDMACH0->CConfig = chnl->conf;
	/* enable channel */
	LPC_GPDMACH0->CConfig |= GPDMA_CH_CFG_CHANNEL_EN;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl1Enable
 description:     enable channel 1
 parameters:      channel settings
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl1Enable (const gpdmaChannel chnl, const uint16 size)
{
	/* clear pending TC interrupt in channel */
	LPC_GPDMA->IntTCClear = GPDMA_INT_TCCLR_INT_TCCLR1;
	/* clear pending errors in channel */
	LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR1;
	/* set source address */
	LPC_GPDMACH1->CSrcAddr = chnl->src;
	/* set destination address */
	LPC_GPDMACH1->CDestAddr = chnl->dst;
	/* no list */
	LPC_GPDMACH1->CLLI = 0;
	/* set control word */
	LPC_GPDMACH1->CControl = chnl->ctrl | (size & GPDMA_CH_CTRL_TRANSFER_SIZE_mask);
	/* set configuration word */
	LPC_GPDMACH1->CConfig = chnl->conf;
	/* enable channel */
	LPC_GPDMACH1->CConfig |= GPDMA_CH_CFG_CHANNEL_EN;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl2Enable
 description:     enable channel 2
 parameters:      channel settings
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl2Enable (const gpdmaChannel chnl, const uint16 size)
{
	/* clear pending TC interrupt in channel */
	LPC_GPDMA->IntTCClear = GPDMA_INT_TCCLR_INT_TCCLR2;
	/* clear pending errors in channel */
	LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR2;
	/* set source address */
	LPC_GPDMACH2->CSrcAddr = chnl->src;
	/* set destination address */
	LPC_GPDMACH2->CDestAddr = chnl->dst;
	/* no list */
	LPC_GPDMACH2->CLLI = 0;
	/* set control word */
	LPC_GPDMACH2->CControl = chnl->ctrl | (size & GPDMA_CH_CTRL_TRANSFER_SIZE_mask);
	/* set configuration word */
	LPC_GPDMACH2->CConfig = chnl->conf;
	/* enable channel */
	LPC_GPDMACH2->CConfig |= GPDMA_CH_CFG_CHANNEL_EN;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl3Enable
 description:     enable channel 3
 parameters:      channel settings
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl3Enable (const gpdmaChannel chnl, const uint16 size)
{
	/* clear pending TC interrupt in channel */
	LPC_GPDMA->IntTCClear = GPDMA_INT_TCCLR_INT_TCCLR3;
	/* clear pending errors in channel */
	LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR3;
	/* set source address */
	LPC_GPDMACH3->CSrcAddr = chnl->src;
	/* set destination address */
	LPC_GPDMACH3->CDestAddr = chnl->dst;
	/* no list */
	LPC_GPDMACH3->CLLI = 0;
	/* set control word */
	LPC_GPDMACH3->CControl = chnl->ctrl | (size & GPDMA_CH_CTRL_TRANSFER_SIZE_mask);
	/* set configuration word */
	LPC_GPDMACH3->CConfig = chnl->conf;
	/* enable channel */
	LPC_GPDMACH3->CConfig |= GPDMA_CH_CFG_CHANNEL_EN;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl4Enable
 description:     enable channel 4
 parameters:      channel settings
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl4Enable (const gpdmaChannel chnl, const uint16 size)
{
	/* clear pending TC interrupt in channel */
	LPC_GPDMA->IntTCClear = GPDMA_INT_TCCLR_INT_TCCLR4;
	/* clear pending errors in channel */
	LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR4;
	/* set source address */
	LPC_GPDMACH4->CSrcAddr = chnl->src;
	/* set destination address */
	LPC_GPDMACH4->CDestAddr = chnl->dst;
	/* no list */
	LPC_GPDMACH4->CLLI = 0;
	/* set control word */
	LPC_GPDMACH4->CControl = chnl->ctrl | (size & GPDMA_CH_CTRL_TRANSFER_SIZE_mask);
	/* set configuration word */
	LPC_GPDMACH4->CConfig = chnl->conf;
	/* enable channel */
	LPC_GPDMACH4->CConfig |= GPDMA_CH_CFG_CHANNEL_EN;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl5Enable
 description:     enable channel 5
 parameters:      channel settings
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl5Enable (const gpdmaChannel chnl, const uint16 size)
{
	/* clear pending TC interrupt in channel */
	LPC_GPDMA->IntTCClear = GPDMA_INT_TCCLR_INT_TCCLR5;
	/* clear pending errors in channel */
	LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR5;
	/* set source address */
	LPC_GPDMACH5->CSrcAddr = chnl->src;
	/* set destination address */
	LPC_GPDMACH5->CDestAddr = chnl->dst;
	/* no list */
	LPC_GPDMACH5->CLLI = 0;
	/* set control word */
	LPC_GPDMACH5->CControl = chnl->ctrl | (size & GPDMA_CH_CTRL_TRANSFER_SIZE_mask);
	/* set configuration word */
	LPC_GPDMACH5->CConfig = chnl->conf;
	/* enable channel */
	LPC_GPDMACH5->CConfig |= GPDMA_CH_CFG_CHANNEL_EN;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl6Enable
 description:     enable channel 6
 parameters:      channel settings
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl6Enable (const gpdmaChannel chnl, const uint16 size)
{
	/* clear pending TC interrupt in channel */
	LPC_GPDMA->IntTCClear = GPDMA_INT_TCCLR_INT_TCCLR6;
	/* clear pending errors in channel */
	LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR6;
	/* set source address */
	LPC_GPDMACH6->CSrcAddr = chnl->src;
	/* set destination address */
	LPC_GPDMACH6->CDestAddr = chnl->dst;
	/* no list */
	LPC_GPDMACH6->CLLI = 0;
	/* set control word */
	LPC_GPDMACH6->CControl = chnl->ctrl | (size & GPDMA_CH_CTRL_TRANSFER_SIZE_mask);
	/* set configuration word */
	LPC_GPDMACH6->CConfig = chnl->conf;
	/* enable channel */
	LPC_GPDMACH6->CConfig |= GPDMA_CH_CFG_CHANNEL_EN;
}

/*------------------------------------------------------------------------------
 function name:   gpdmaChnl7Enable
 description:     enable channel 7
 parameters:      channel settings
 returned value:  none
------------------------------------------------------------------------------*/
void gpdmaChnl7Enable (const gpdmaChannel chnl, const uint16 size)
{
	/* clear pending TC interrupt in channel */
	LPC_GPDMA->IntTCClear = GPDMA_INT_TCCLR_INT_TCCLR7;
	/* clear pending errors in channel */
	LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR7;
	/* set source address */
	LPC_GPDMACH7->CSrcAddr = chnl->src;
	/* set destination address */
	LPC_GPDMACH7->CDestAddr = chnl->dst;
	/* no list */
	LPC_GPDMACH7->CLLI = 0;
	/* set control word */
	LPC_GPDMACH7->CControl = chnl->ctrl | (size & GPDMA_CH_CTRL_TRANSFER_SIZE_mask);
	/* set configuration word */
	LPC_GPDMACH7->CConfig = chnl->conf;
	/* enable channel */
	LPC_GPDMACH7->CConfig |= GPDMA_CH_CFG_CHANNEL_EN;
}
/*==============================================================================
 Static function definitions
==============================================================================*/
/*------------------------------------------------------------------------------
 function name:   dummyService
 description:     does nothing
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/
static void dummyService (void)
{
   return;
}

/*==============================================================================
 ISR definitions
==============================================================================*/
/*------------------------------------------------------------------------------
 function name:   DMA_IRQHandler
 description:     GPDMA ISR
 parameters:      none
 returned value:  none
------------------------------------------------------------------------------*/
void DMA_IRQHandler (void)
{
	uint32 reg = LPC_GPDMA->IntTCStat & 0xFF;				/* only 8 bits are meaningful */

   /* terminal count interrupt- transfer completed */
   if (reg & GPDMA_INT_TCSTAT_INT_TCSTATUS0)
   {
	  LPC_GPDMA->IntTCClear = GPDMA_INT_TCSTAT_INT_TCSTATUS0;   	/* clear interrupt */
      serviceArray[0].transferEndService();                 		/* call user service */
   }
   if (reg & GPDMA_INT_TCSTAT_INT_TCSTATUS1)
   {
	  LPC_GPDMA->IntTCClear = GPDMA_INT_TCSTAT_INT_TCSTATUS1;   	/* clear interrupt */
      serviceArray[1].transferEndService();                 		/* call user service */
   }
   if (reg & GPDMA_INT_TCSTAT_INT_TCSTATUS2)
   {
	  LPC_GPDMA->IntTCClear = GPDMA_INT_TCSTAT_INT_TCSTATUS2;   	/* clear interrupt */
      serviceArray[2].transferEndService();                 		/* call user service */
   }
   if (reg & GPDMA_INT_TCSTAT_INT_TCSTATUS3)
   {
	  LPC_GPDMA->IntTCClear = GPDMA_INT_TCSTAT_INT_TCSTATUS3;   	/* clear interrupt */
      serviceArray[3].transferEndService();                 		/* call user service */
   }
   if (reg & GPDMA_INT_TCSTAT_INT_TCSTATUS4)
   {
	  LPC_GPDMA->IntTCClear = GPDMA_INT_TCSTAT_INT_TCSTATUS4;   	/* clear interrupt */
      serviceArray[4].transferEndService();                 		/* call user service */
   }
   if (reg & GPDMA_INT_TCSTAT_INT_TCSTATUS5)
   {
	  LPC_GPDMA->IntTCClear = GPDMA_INT_TCSTAT_INT_TCSTATUS5;   	/* clear interrupt */
      serviceArray[5].transferEndService();                 		/* call user service */
   }
   if (reg & GPDMA_INT_TCSTAT_INT_TCSTATUS6)
   {
	  LPC_GPDMA->IntTCClear = GPDMA_INT_TCSTAT_INT_TCSTATUS6;   	/* clear interrupt */
      serviceArray[6].transferEndService();                 		/* call user service */
   }
   if (reg & GPDMA_INT_TCSTAT_INT_TCSTATUS7)
   {
	  LPC_GPDMA->IntTCClear = GPDMA_INT_TCSTAT_INT_TCSTATUS7;   	/* clear interrupt */
      serviceArray[7].transferEndService();                 		/* call user service */
   }

   /* error interrupt */
   reg = LPC_GPDMA->IntErrStat & 0xFF;						/* only 8 bits are meaningful */
   if (reg & GPDMA_INT_ERR_CLR_INT_ERR0)
   {
      LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR0;      	/* clear interrupt */
      serviceArray[0].errorService();                       	/* call user service */
   }
   if (reg & GPDMA_INT_ERR_CLR_INT_ERR1)
   {
      LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR1;      	/* clear interrupt */
      serviceArray[1].errorService();                       	/* call user service */
   }
   if (reg & GPDMA_INT_ERR_CLR_INT_ERR2)
   {
      LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR2;      	/* clear interrupt */
      serviceArray[2].errorService();                       	/* call user service */
   }
   if (reg & GPDMA_INT_ERR_CLR_INT_ERR3)
   {
      LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR3;      	/* clear interrupt */
      serviceArray[3].errorService();                       	/* call user service */
   }
   if (reg & GPDMA_INT_ERR_CLR_INT_ERR4)
   {
      LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR4;      	/* clear interrupt */
      serviceArray[4].errorService();                       	/* call user service */
   }
   if (reg & GPDMA_INT_ERR_CLR_INT_ERR5)
   {
      LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR5;      	/* clear interrupt */
      serviceArray[5].errorService();                       	/* call user service */
   }
   if (reg & GPDMA_INT_ERR_CLR_INT_ERR6)
   {
      LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR6;      	/* clear interrupt */
      serviceArray[6].errorService();                       	/* call user service */
   }
   if (reg & GPDMA_INT_ERR_CLR_INT_ERR7)
   {
      LPC_GPDMA->IntErrClr = GPDMA_INT_ERR_CLR_INT_ERR7;      	/* clear interrupt */
      serviceArray[7].errorService();                       	/* call user service */
   }
}

/******************************************************************************
* END OF FILE
******************************************************************************/


